{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Parallel computing on multivectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "using Distributed\n",
    "using DistributedArrays\n",
    "addprocs(4);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "@everywhere using JOLI\n",
    "@everywhere using LinearAlgebra"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Setup problem size, define operator, and input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "M=8;\n",
    "NVC=15;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type: joLinearFunction\n",
      "Name: joDFT\n",
      "Size: (8, 8)\n",
      " DDT: Float64\n",
      " RDT: Complex{Float64}\n"
     ]
    }
   ],
   "source": [
    "A=joDFT(M,planned=false);\n",
    "show(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8×15 Array{Float64,2}:\n",
       "  0.199576   0.432885   0.0204887  …   1.47038    -0.0159484  -0.410357 \n",
       "  0.845953  -2.00127    0.552835       0.383823   -1.62674     0.0210648\n",
       "  0.811466   0.485418  -0.760596      -0.211384   -2.16644    -0.72407  \n",
       "  1.17695   -0.800166  -1.50023       -1.33047    -0.538085   -0.298732 \n",
       "  0.141245  -0.140401  -0.492261      -0.0149375  -0.808913    0.513472 \n",
       " -0.545118   0.300894   0.0444384  …  -1.45843    -0.36587    -0.413716 \n",
       "  0.921992   0.905117  -0.369768       0.617279   -0.949343    0.720445 \n",
       " -0.140138   0.887322   1.25449       -0.678948   -0.270405   -0.461295 "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=randn(M,NVC)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using Distributed Ararys"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Define parallel setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "joPAsetup: joPAsetup\n",
      " DataType: Float64\n",
      " Dims    : (8, 15)\n",
      " Chunks  : [1, 4]\n",
      " Workers : [2, 3, 4, 5]\n",
      "  Worker/ranges:   2 (1:8, 1:4)\n",
      "  Worker/ranges:   3 (1:8, 5:8)\n",
      "  Worker/ranges:   4 (1:8, 9:12)\n",
      "  Worker/ranges:   5 (1:8, 13:15)\n"
     ]
    }
   ],
   "source": [
    "ps=joPAsetup((M,NVC));\n",
    "show(ps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Define parallel operator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type: joDAdistributedLinearOperator\n",
      "Name: joDAdistributedLinearOperator(joDFT)\n",
      "Size: (8, 8)\n",
      " NVC: 15\n",
      " DDT: Float64\n",
      " RDT: Complex{Float64}\n"
     ]
    }
   ],
   "source": [
    "pA=joDAdistributedLinOp(A,ps);\n",
    "show(pA)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Define distributed array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      From worker 5:\t5(1:8, 13:15)(8, 3)\n",
      "      From worker 3:\t3(1:8, 5:8)(8, 4)\n",
      "      From worker 4:\t4(1:8, 9:12)(8, 4)\n",
      "      From worker 2:\t2(1:8, 1:4)(8, 4)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "8×15 DArray{Float64,2,Array{Float64,2}}:\n",
       "  0.199576   0.432885   0.0204887  …   1.47038    -0.0159484  -0.410357 \n",
       "  0.845953  -2.00127    0.552835       0.383823   -1.62674     0.0210648\n",
       "  0.811466   0.485418  -0.760596      -0.211384   -2.16644    -0.72407  \n",
       "  1.17695   -0.800166  -1.50023       -1.33047    -0.538085   -0.298732 \n",
       "  0.141245  -0.140401  -0.492261      -0.0149375  -0.808913    0.513472 \n",
       " -0.545118   0.300894   0.0444384  …  -1.45843    -0.36587    -0.413716 \n",
       "  0.921992   0.905117  -0.369768       0.617279   -0.949343    0.720445 \n",
       " -0.140138   0.887322   1.25449       -0.678948   -0.270405   -0.461295 "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@everywhere function fillin(x,n)\n",
    "    println(myid(),n,(length(n[1]),length(n[2])))\n",
    "    x[n...]\n",
    "end\n",
    "\n",
    "px=dfill(r->fillin(x,r),ps)\n",
    "px"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Just parallel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8×15 DArray{Complex{Float64},2,Array{Complex{Float64},2}}:\n",
       "     1.2063+0.0im       0.0246775+0.0im       …  -0.372358+0.0im     \n",
       "  0.0391187-0.637963im  0.0490182+1.1458im       -0.258568+0.361377im\n",
       "  -0.492371+0.260207im   -0.38822+0.631988im      0.037738-0.129887im\n",
       " 0.00212725-0.716117im   0.356356+0.849027im     -0.394677-0.660049im\n",
       "   0.260439+0.0im          1.1654+0.0im           0.442708+0.0im     \n",
       " 0.00212725+0.716117im   0.356356-0.849027im  …  -0.394677+0.660049im\n",
       "  -0.492371-0.260207im   -0.38822-0.631988im      0.037738+0.129887im\n",
       "  0.0391187+0.637963im  0.0490182-1.1458im       -0.258568-0.361377im"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "py=pA*px"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Serial to serial via parallel"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Define distrtibuting and gathering operators"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type: joDAdistribute\n",
      "Name: joDAdistributeMV:15\n",
      "Size: (8, 8)\n",
      " NVC: 15\n",
      " DDT: Float64\n",
      " RDT: Float64\n"
     ]
    }
   ],
   "source": [
    "pD=joDAdistribute(pA);\n",
    "show(pD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type: joDAgather\n",
      "Name: joDAgatherMV:15\n",
      "Size: (8, 8)\n",
      " NVC: 15\n",
      " DDT: Complex{Float64}\n",
      " RDT: Complex{Float64}\n"
     ]
    }
   ],
   "source": [
    "pG=joDAgather(pA);\n",
    "show(pG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Distribute data, apply operator, gather data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8×15 DArray{Float64,2,Array{Float64,2}}:\n",
       "  0.199576   0.432885   0.0204887  …   1.47038    -0.0159484  -0.410357 \n",
       "  0.845953  -2.00127    0.552835       0.383823   -1.62674     0.0210648\n",
       "  0.811466   0.485418  -0.760596      -0.211384   -2.16644    -0.72407  \n",
       "  1.17695   -0.800166  -1.50023       -1.33047    -0.538085   -0.298732 \n",
       "  0.141245  -0.140401  -0.492261      -0.0149375  -0.808913    0.513472 \n",
       " -0.545118   0.300894   0.0444384  …  -1.45843    -0.36587    -0.413716 \n",
       "  0.921992   0.905117  -0.369768       0.617279   -0.949343    0.720445 \n",
       " -0.140138   0.887322   1.25449       -0.678948   -0.270405   -0.461295 "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "px=pD*x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8×15 DArray{Complex{Float64},2,Array{Complex{Float64},2}}:\n",
       "     1.2063+0.0im       0.0246775+0.0im       …  -0.372358+0.0im     \n",
       "  0.0391187-0.637963im  0.0490182+1.1458im       -0.258568+0.361377im\n",
       "  -0.492371+0.260207im   -0.38822+0.631988im      0.037738-0.129887im\n",
       " 0.00212725-0.716117im   0.356356+0.849027im     -0.394677-0.660049im\n",
       "   0.260439+0.0im          1.1654+0.0im           0.442708+0.0im     \n",
       " 0.00212725+0.716117im   0.356356-0.849027im  …  -0.394677+0.660049im\n",
       "  -0.492371-0.260207im   -0.38822-0.631988im      0.037738+0.129887im\n",
       "  0.0391187+0.637963im  0.0490182-1.1458im       -0.258568-0.361377im"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "py=pA*px"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8×15 Array{Complex{Float64},2}:\n",
       "     1.2063+0.0im       0.0246775+0.0im       …  -0.372358+0.0im     \n",
       "  0.0391187-0.637963im  0.0490182+1.1458im       -0.258568+0.361377im\n",
       "  -0.492371+0.260207im   -0.38822+0.631988im      0.037738-0.129887im\n",
       " 0.00212725-0.716117im   0.356356+0.849027im     -0.394677-0.660049im\n",
       "   0.260439+0.0im          1.1654+0.0im           0.442708+0.0im     \n",
       " 0.00212725+0.716117im   0.356356-0.849027im  …  -0.394677+0.660049im\n",
       "  -0.492371-0.260207im   -0.38822-0.631988im      0.037738+0.129887im\n",
       "  0.0391187+0.637963im  0.0490182-1.1458im       -0.258568-0.361377im"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y=pG*py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Or all together"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Type: joLinearOperator\n",
      "Name: ((joDAgatherMV:15*joDAdistributedLinearOperator(joDFT))*joDAdistributeMV:15)\n",
      "Size: (8, 8)\n",
      " DDT: Float64\n",
      " RDT: Complex{Float64}\n"
     ]
    }
   ],
   "source": [
    "ps2s=pG*pA*pD\n",
    "show(ps2s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8×15 Array{Complex{Float64},2}:\n",
       "     1.2063+0.0im       0.0246775+0.0im       …  -0.372358+0.0im     \n",
       "  0.0391187-0.637963im  0.0490182+1.1458im       -0.258568+0.361377im\n",
       "  -0.492371+0.260207im   -0.38822+0.631988im      0.037738-0.129887im\n",
       " 0.00212725-0.716117im   0.356356+0.849027im     -0.394677-0.660049im\n",
       "   0.260439+0.0im          1.1654+0.0im           0.442708+0.0im     \n",
       " 0.00212725+0.716117im   0.356356-0.849027im  …  -0.394677+0.660049im\n",
       "  -0.492371-0.260207im   -0.38822-0.631988im      0.037738+0.129887im\n",
       "  0.0391187+0.637963im  0.0490182-1.1458im       -0.258568-0.361377im"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y=ps2s*x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.3.1",
   "language": "julia",
   "name": "julia-1.3"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.3.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
